﻿// 1124. 骑马修栅栏.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

/*

https://www.acwing.com/problem/content/1126/

农民John每年有很多栅栏要修理。

他总是骑着马穿过每一个栅栏并修复它破损的地方。

John是一个与其他农民一样懒的人。

他讨厌骑马，因此从来不两次经过一个栅栏。 

你必须编一个程序，读入栅栏网络的描述，并计算出一条修栅栏的路径，使每个栅栏都恰好被经过一次。

John能从任何一个顶点(即两个栅栏的交点)开始骑马，在任意一个顶点结束。

每一个栅栏连接两个顶点，顶点用 1 到 500 标号(虽然有的农场并没有 500 个顶点)。

一个顶点上可连接任意多( ≥1 )个栅栏。

所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。

你的程序必须输出骑马的路径(用路上依次经过的顶点号码表示)。

我们如果把输出的路径看成是一个500进制的数，那么当存在多组解的情况下，输出500进制表示法中最小的一个 
(也就是输出第一个数较小的，如果还有多组解，输出第二个数较小的，等等)。

输入数据保证至少有一个解。

输入格式
第 1 行:一个整数 F，表示栅栏的数目;

第 2 到 F+1 行:每行两个整数 i,j 表示这条栅栏连接 i 与 j 号顶点。

输出格式
输出应当有 F+1 行，每行一个整数，依次表示路径经过的顶点号。

注意数据可能有多组解，但是只有上面题目要求的那一组解是认为正确的。

数据范围
1≤F≤1024,
1≤i,j≤500
输入样例：
9
1 2
2 3
3 4
4 2
4 5
2 5
5 6
5 7
4 6
输出样例：
1
2
3
4
2
5
4
6
5
7
*/



#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 505, M = 1050;
int g[N][N];
int n, m;
int d[N];
int cnt;
int ans[M];

void dfs(int u) {
	for (int i = 1; i <= n; i++) {
		if (g[u][i]) {
			g[u][i]--; g[i][u]--;
			dfs(i);
		}
	}

	ans[cnt++] = u;
}

int main() {
	cin >> m;
	while (m--) {
		int a, b; cin >> a >> b;
		g[a][b]++; g[b][a]++;
		d[a]++, d[b]++;
	}
	n = 500;
	int start = 1;
	for (int i = 1; i <= n; i++) {
		if (d[i] != 0) { start = i; break; }
	}
	for (int i = 1; i <= n; i++) {
		if (d[i] & 1) { start = i; break; }
	}

	dfs(start);


	for (int i = cnt - 1; i >= 0; i--) {
		cout << ans[i] << endl;
	}

	return 0;
}